﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using Ping.App;
using Ping.App.Jobs;
using Ping.Core;

namespace Ping.Client.Controls
{
	public partial class AddressControl
	{
		private Job _currentJob;

		public AddressControl()
		{
			InitializeComponent();
			Loaded += ControlLoaded;
		}

		public string Address
		{
			get { return tb_ip.Text; }
		}

		public event RequestHandler RequestFinished;

		private void ControlLoaded(object sender, RoutedEventArgs e)
		{
		}

		/// <summary>
		/// Tests if the given text is a valid uri or ipaddress...
		/// </summary>
		/// <param name="text"></param>
		/// <returns></returns>
		private static bool IsValid(string text)
		{
			IPAddress unused1;
			return IPAddress.TryParse(text, out unused1) ||
			       Uri.IsWellFormedUriString(text, UriKind.RelativeOrAbsolute);
		}

		public static bool IsIpAddress(string text)
		{
			IPAddress unused;
			return IPAddress.TryParse(text, out unused);
		}

		private void ResolveClick(object sender, RoutedEventArgs e)
		{
			if (_currentJob != null)
				throw new InvalidOperationException("A job is already executing");

			if (IsIpAddress(Address))
			{
				var result = new DnsResult {Addresses = new[] {IpAddress.Parse(Address)}};
				EndRequest(result, null);
			}
			else
			{
				var request = new DnsRequest {Domain = Address};
				_currentJob = StateService.State.Scheduler.GetJob(request);
				_currentJob.Perform(request, EndRequest);
			}

			UpdateControl();
		}

		private void TextChanged(object sender, TextChangedEventArgs e)
		{
			UpdateControl();
		}

		private void EndRequest(Result result, Exception e)
		{
			Dispatcher.BeginInvoke(() =>
			                       	{
			                       		_currentJob = null;

			                       		if (RequestFinished != null)
			                       			RequestFinished(result, e);

			                       		UpdateControl();
			                       	});
		}

		/// <summary>
		/// Updates this page according to the current state...
		/// </summary>
		private void UpdateControl()
		{
			// There can be only one job...
			if (_currentJob != null)
			{
				dns.IsEnabled = false;
				tb_ip.IsEnabled = false;
				loading.Visibility = Visibility.Visible;
			}
			else
			{
				tb_ip.IsEnabled = true;
				dns.IsEnabled = IsValid(tb_ip.Text);
				loading.Visibility = Visibility.Collapsed;
			}
		}
	}
}